const path = require('path');
const webpack = require('webpack');
const HmtlWebpackPlugin = require('html-webpack-plugin');
// const process = require('process');//全局变量，所以无需使用 require()

const config = {
    projectName: 'webpack-test',
    isProductionEnv: (() => {
        return process.env.NODE_DEV === 'production';
    })(),
    //process.cwd() -- 当前执行node命令时候的文件夹地址
    //__dirname -- 当前模块的目录名
    basePath: process.cwd(),
    entryBasePath: path.resolve(process.cwd(), 'src'),
    outPutBasePath: path.resolve(process.cwd(), 'dist'),
    apps: ["main", "home"]
}

/**
 * 入口chunk
 */
const entrys = (() => {
    const entrys = config.apps.reduce((prev, app) => {
        prev[app] = [
            'babel-polyfill',
            path.resolve(config.entryBasePath, app, 'index')
        ]
        return prev;
    }, {});
    return entrys;
})();

/**
 * 文件模板
 */
const htmlWebpackPlugins = (() => {
    return config.apps.map((app) => {
        const tmplPath = path.join(config.entryBasePath, '/tmpl/index.ejs');
        return new HmtlWebpackPlugin({
            title: "测试", //<%=htmlWebpackPlugin.options.title%>
            filename: `${config.outPutBasePath}/${app}/index.html`,
            template: tmplPath,
            hash: true,
            cache: true,
            // inject: false,//是否注入
            minify: {
                //删除注释，但是会保留script和style中的注释
                removeComments: config.isProductionEnv,
                //从脚本和样式删除的注释
                removeCommentsFromCDATA: config.isProductionEnv,
                minifyJS: config.isProductionEnv,
                minifyCSS: config.isProductionEnv,
                minifyURLs: config.isProductionEnv
            },
            chunks: [
                app
            ],
            alwaysWriteToDisk: true,
        });
    });
})();

const serverSetup = (app) => {
    // app.get('/some/path', function (req, res) {
    //     res.json({
    //         custom: 'response'
    //     });
    // });
    // app.get('/main', (req, res) => {
    //     res.send('test');
    // });
    // config.apps.forEach((app) => {
    //     app.get(`/${app}`, require(path.resolve(config.outPutBasePath, app, 'index.html')));
    // })
}

const devServer = (() => {
    return {
        //设置默认监听端口，如果省略，默认为”8080“
        port: "9999",
        //默认webpack-dev-server会为根文件夹提供本地服务器，如果想为另外一个目录下的文件提供本地服务器，应该在这里设置其所在目录（本例设置到“public"目录）
        contentBase: config.outPutBasePath,
        //在开发单页应用时非常有用，它依赖于HTML5 history API，如果设置为true，所有的跳转将指向index.html
        historyApiFallback: true,
        //设置为true，当源文件改变时会自动刷新页面
        inline: true,
        // setup: serverSetup,
        open: true,
        openPage: `/${config.apps[0]}`
    };
})();

const webpackConfig = {
    entry: entrys, //入口文件
    output: {
        path: config.outPutBasePath, //打包后的文件存放位置
        publicPath: '',
        filename: "[name]/js/[name].js", //"./[name]/bundle.[chunkhash:4].js",//打包后文件名
        chunkFilename: "[id].js"
    },
    //在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map，但是它会减慢打包速度；
    // devtool: "source-map",
    //在一个单独的文件中生成一个不带列映射的map，不带列映射提高了打包速度，但是也使得浏览器开发者工具只能对应到具体的行，不能对应到具体的列（符号），会对调试造成不便；
    devtool: "cheap-module-source-map",
    //使用eval打包源文件模块，在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap，但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项，在生产阶段则一定不要启用这个选项；
    // devtool: "eval-source-map",
    //这是在打包文件时最快的生成source map的方法，生成的Source Map 会和打包后的JavaScript文件同行显示，没有列映射，和eval-source-map选项具有相似的缺点；
    // devtool: "cheap-module-eval-source-map",
    devServer: devServer,
    module: {
        rules: [{
                test: /(\.jsx|\.js)$/,
                use: {
                    loader: 'babel-loader?cacheDirectory=true',
                    //Babel其实可以完全在 webpack.config.js 中进行配置，但是考虑到babel具有非常多的配置选项，在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂，因此一些开发者支持把babel的配置选项放在一个单独的名为 ".babelrc" 的配置文件中
                    // options: {
                    //     //环境：env react es7新特性，箭头函数等：stage-0
                    //     presets: ["env", "react", "stage-0"]
                    // }
                },
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                use: [
                    //同一个文件引入多个loader
                    {
                        loader: "style-loader"
                    },
                    {
                        loader: "css-loader",
                        options: {
                            modules: true, //指定启用css modules
                            minimize: true, //启用压缩
                            sourceMap: true, //启用sourcemap
                            localIdentName: '[name]__[local]--[hash:base64:5]', //指定的css的类名格式
                        }
                    },
                    {
                        //postcss.config.js
                        loader: "postcss-loader"
                    }
                ]
            }
        ]
    },
    plugins: [
        //http://www.css88.com/doc/webpack/plugins/
        new webpack.BannerPlugin('版权所有，翻版必究'),
        //https://github.com/jantimon/html-webpack-plugin#configuration
        //生成多个html文件，多次声明这个插件在plugins 数组中
        ...htmlWebpackPlugins
    ]
};

module.exports = webpackConfig;